﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.Runtime.Serialization;

namespace DistributedGame
{
    [Serializable,DataContract]
    public class ClientConnectRequest
    {
		//[NonSerialized]
		
        [DataMember]
        public string Name { get; internal set; }
    }

    [Serializable,DataContract]
    public class ClientConnectionInfo
    {
        [DataMember]
        public string SessionId { get; internal set; }
		
        [DataMember]
        public string Nick { get; internal set; }
        
        /// Possible other properties:
		/// - Network Address (URI)
		/// - Client Version
		/// - DateTime connected
    }

    [Serializable,DataContract]
    public class Message
    {
        [DataMember]
        public string SenderId { get; internal set; }
        
        [DataMember]
        public string Content { get; internal set; }
        
        [DataMember]
        public DateTime Time { get; internal set; }
    }
    
    [ServiceContract(CallbackContract = typeof(IGameClientCallback), SessionMode = SessionMode.Required)]
    public interface IGameHost
    {
		/// TODO:
		/// - Authentication / Authorization
		/// - Connection keep-alive [DONE - http://www.smartasses.be/2009/01/26/wcf-reliable-session-and-keep-alives/ ]
		/// - Client reconnect after fault (i.e., keeps game state and player slot until Server decides to close it)
		/// - Separate concepts of GameClient and GamePlayer (e.g., two players can play from the same remote client)
		/// - Handle exceptions that occur on asynchronous events
		/// - Game ideas:
		/// 	- Modulus N
		/// 	- Amazons
		/// 	- http://en.wikipedia.org/wiki/List_of_abstract_strategy_games
		
		[OperationContract(IsInitiating = true)]
		ClientConnectionInfo Connect(ClientConnectRequest request);

		[OperationContract(IsOneWay = true)]
		void Say(string message);

		//[OperationContract(IsOneWay = true)]
		//void Whisper(string msg, ClientInfo receiver);

		//[OperationContract(IsOneWay = true)]
		//void IsWriting(ClientInfo client);

		[OperationContract(IsOneWay = true, IsTerminating = true)]
		void Disconnect();
    }

    public interface IGameClientCallback
    {
		[OperationContract(IsOneWay = true)]
		void Receive(string message);

		[OperationContract(IsOneWay = true)]
		void RefreshClients(IList<ClientConnectionInfo> clients);

		//[OperationContract(IsOneWay = true)]
		//void Receive(Message message);

		//[OperationContract(IsOneWay = true)]
		//void ClientIsTyping(ClientInfo client);

		//[OperationContract(IsOneWay = true)]
		//void ClientJoined(ClientInfo client);

		//[OperationContract(IsOneWay = true)]
		//void ClientLeft(ClientInfo client);

		[OperationContract(IsOneWay = true, IsTerminating = true)]
		//[OperationBehavior(ReleaseInstanceMode=ReleaseInstanceMode.AfterCall)]
		void ServerClosing();
    }
}
